﻿using System.Collections.Generic;
using System.Linq;
using Ease.EaseNode.Runtime;
using Sirenix.OdinInspector;
using UnityEngine;

namespace Ease.EaseMission.Runtime
{
    public class MissionManager : MonoBehaviour, IMissionManager, IDataSoHolder<MissionDataSo>
    {
        [SerializeField] private MissionDataSo dataSo;

        public MissionDataSo DataSo => dataSo;

        [ShowInInspector] private RunState currentState = RunState.NONE;
        private List<MissionStage> stages = new List<MissionStage>();
        private List<MissionStageHandler> handlers = new List<MissionStageHandler>();

        public RunState CurrentState
        {
            get => currentState;
            set => currentState = value;
        }

        public static MissionManager Instanc;

        private void Awake()
        {
            Instanc = this;
        }

        private void OnDestroy()
        {
            Instanc = null;
        }

        [Button]
        public void StartMission()
        {
            if (!Application.isPlaying)
                return;
            foreach (var missionStageHandler in handlers)
            {
                missionStageHandler.Reset();
            }

            handlers.Clear();
            stages.AddRange(dataSo.datas);
            TryStartNewAgent();
        }

        [Button]
        public void Reset()
        {
            foreach (var missionStageHandler in handlers)
            {
                missionStageHandler.Reset();
            }
        }

        private void OnStateChange(RunState runState)
        {
            if (runState == RunState.FINISH)
                TryStartNewAgent();
        }

        private void TryStartNewAgent()
        {
            if (stages.Count <= 0)
            {
                CurrentState = RunState.FINISH;
                foreach (var handler in handlers)
                {
                    handler.OnRunStateChange -= OnStateChange;
                }

                return;
            }

            CurrentState = RunState.ACTIVED;
            var stage = stages.First();
            stages.RemoveAt(0);
            var stageHandler = GetHandler<MissionStageHandler>(stage, handlers);
            stageHandler.OnRunStateChange -= OnStateChange;
            stageHandler.OnRunStateChange += OnStateChange;
            stageHandler.Start();
        }

        private T GetHandler<T>(IEaseNodeData data, List<T> handles) where T : class, IEaseNodeAgent
        {
            var target = handles.FirstOrDefault(x => x.Data == data);
            if (target != null)
            {
                return target;
            }
            else
            {
                target = data.CreateAgent() as T;
                handles.Add(target);
            }

            return target;
        }
    }
}